/*
 *  Copyright 2012 yura.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package org.opu.odg.m_ui;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ResourceBundle;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.opu.odg.dg.DocumentGeneraionService;
import org.opu.odg.dg.GenerationSettings;
import org.opu.odg.dg.impl.ConnectionHolder;
import org.opu.odg.dg.incomingdata.DatabaseSettings;
import org.opu.odg.dg.logicbeans.Template;
import org.opu.odg.dg.util.XmlSerializator;
import org.opu.odg.m_ui.tmp.TemplateRepositoryImpl;
import org.opu.odg.m_ui.tmp.TemplateRepositoryImpl.TemplateBean;
import org.opu.odg.m_ui.util.UIUtil;
import org.opu.odg.m_ui.util.UIUtil.ProgressDialog;

/**
 *
 * @author yura
 */
public class MainFrame extends javax.swing.JFrame {

    private TemplateRepositoryImpl templateRepository;
    private DocumentGeneraionService generaionService;
    private ConnectionHolder connectionHolder;
    private File defaultDatabaseSettingsFileName;

    private ResourceBundle bundle = ResourceBundle.getBundle("org.opu.odg.m_ui.Bundle");
    private DefaultListModel listModel = new DefaultListModel();

    /** Creates new form MainFrame */
    public MainFrame(TemplateRepositoryImpl templateRepository,
            DocumentGeneraionService generaionService,
            ConnectionHolder connectionHolder,
            File defaultDatabaseSettingsFileName) {
        this.templateRepository = templateRepository;
        this.generaionService = generaionService;
        this.connectionHolder = connectionHolder;
        this.defaultDatabaseSettingsFileName = defaultDatabaseSettingsFileName;
        for(TemplateBean b : templateRepository.getList()) {
            listModel.addElement(b);
        }
        initComponents();

        mainList.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() >=2) {
                    editBtnActionPerformed(null);
                } else if (e.getButton() == MouseEvent.BUTTON2) {
                    // context menu
                }
            }

        });
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        toolbarPanel = new javax.swing.JPanel();
        newBtn = new javax.swing.JButton();
        deleteBtn = new javax.swing.JButton();
        editBtn = new javax.swing.JButton();
        getBtn = new javax.swing.JButton();
        refreshBtn = new javax.swing.JButton();
        mainScroll = new javax.swing.JScrollPane();
        mainList = new javax.swing.JList();
        jMenuBar1 = new javax.swing.JMenuBar();
        managementMenu = new javax.swing.JMenu();
        generateDocumentFromXmlMenuItem = new javax.swing.JMenuItem();
        generateDocumentMenuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        settingsMenuItem = new javax.swing.JMenuItem();
        refreshMenuItem = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        exitMenuItem = new javax.swing.JMenuItem();
        templateMenu = new javax.swing.JMenu();
        newTemplateMenyItem = new javax.swing.JMenuItem();
        deleteTemplateMenyItem = new javax.swing.JMenuItem();
        editTemplateMenyItem = new javax.swing.JMenuItem();
        getTemplateMenyItem = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        copyWithAnotherDataMenuItem = new javax.swing.JMenuItem();
        helpMenu = new javax.swing.JMenu();
        helpMenuItem = new javax.swing.JMenuItem();
        aboutMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle(bundle.getString("title")); // NOI18N

        mainPanel.setLayout(new java.awt.BorderLayout());

        toolbarPanel.setLayout(new javax.swing.BoxLayout(toolbarPanel, javax.swing.BoxLayout.LINE_AXIS));

        newBtn.setText(bundle.getString("template.new")); // NOI18N
        newBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newBtnActionPerformed(evt);
            }
        });
        toolbarPanel.add(newBtn);

        deleteBtn.setText(bundle.getString("template.delete")); // NOI18N
        deleteBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteBtnActionPerformed(evt);
            }
        });
        toolbarPanel.add(deleteBtn);

        editBtn.setText(bundle.getString("template.edit")); // NOI18N
        editBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editBtnActionPerformed(evt);
            }
        });
        toolbarPanel.add(editBtn);

        getBtn.setText(bundle.getString("template.get")); // NOI18N
        getBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getBtnActionPerformed(evt);
            }
        });
        toolbarPanel.add(getBtn);

        refreshBtn.setText(bundle.getString("template.refresh")); // NOI18N
        refreshBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshBtnActionPerformed(evt);
            }
        });
        toolbarPanel.add(refreshBtn);

        mainPanel.add(toolbarPanel, java.awt.BorderLayout.PAGE_START);

        mainList.setModel(listModel);
        mainList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        mainScroll.setViewportView(mainList);

        mainPanel.add(mainScroll, java.awt.BorderLayout.CENTER);

        getContentPane().add(mainPanel, java.awt.BorderLayout.CENTER);

        managementMenu.setText(bundle.getString("management")); // NOI18N

        generateDocumentFromXmlMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_G, java.awt.event.InputEvent.CTRL_MASK));
        generateDocumentFromXmlMenuItem.setText(bundle.getString("generateDocumentFromXml")); // NOI18N
        generateDocumentFromXmlMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                generateDocumentFromXmlMenuItemActionPerformed(evt);
            }
        });
        managementMenu.add(generateDocumentFromXmlMenuItem);

        generateDocumentMenuItem.setText(bundle.getString("generateDocument")); // NOI18N
        generateDocumentMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                generateDocumentMenuItemActionPerformed(evt);
            }
        });
        managementMenu.add(generateDocumentMenuItem);
        managementMenu.add(jSeparator1);

        settingsMenuItem.setText(bundle.getString("settings")); // NOI18N
        settingsMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                settingsMenuItemActionPerformed(evt);
            }
        });
        managementMenu.add(settingsMenuItem);

        refreshMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.CTRL_MASK));
        refreshMenuItem.setText(bundle.getString("template.refresh")); // NOI18N
        refreshMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshMenuItemActionPerformed(evt);
            }
        });
        managementMenu.add(refreshMenuItem);
        managementMenu.add(jSeparator2);

        exitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        exitMenuItem.setText(bundle.getString("exit")); // NOI18N
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        managementMenu.add(exitMenuItem);

        jMenuBar1.add(managementMenu);

        templateMenu.setText(bundle.getString("template")); // NOI18N

        newTemplateMenyItem.setText(bundle.getString("template.new")); // NOI18N
        newTemplateMenyItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newTemplateMenyItemActionPerformed(evt);
            }
        });
        templateMenu.add(newTemplateMenyItem);

        deleteTemplateMenyItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0));
        deleteTemplateMenyItem.setText(bundle.getString("template.delete")); // NOI18N
        deleteTemplateMenyItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteTemplateMenyItemActionPerformed(evt);
            }
        });
        templateMenu.add(deleteTemplateMenyItem);

        editTemplateMenyItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.CTRL_MASK));
        editTemplateMenyItem.setText(bundle.getString("template.edit")); // NOI18N
        editTemplateMenyItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editTemplateMenyItemActionPerformed(evt);
            }
        });
        templateMenu.add(editTemplateMenyItem);

        getTemplateMenyItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_G, java.awt.event.InputEvent.CTRL_MASK));
        getTemplateMenyItem.setText(bundle.getString("template.get")); // NOI18N
        getTemplateMenyItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getTemplateMenyItemActionPerformed(evt);
            }
        });
        templateMenu.add(getTemplateMenyItem);
        templateMenu.add(jSeparator3);

        copyWithAnotherDataMenuItem.setText(bundle.getString("template.copyWithAnotherData")); // NOI18N
        copyWithAnotherDataMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                copyWithAnotherDataMenuItemActionPerformed(evt);
            }
        });
        templateMenu.add(copyWithAnotherDataMenuItem);

        jMenuBar1.add(templateMenu);

        helpMenu.setText(bundle.getString("help")); // NOI18N

        helpMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
        helpMenuItem.setText(bundle.getString("help.context")); // NOI18N
        helpMenu.add(helpMenuItem);

        aboutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        aboutMenuItem.setText(bundle.getString("help.about")); // NOI18N
        helpMenu.add(aboutMenuItem);

        jMenuBar1.add(helpMenu);

        setJMenuBar(jMenuBar1);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-632)/2, (screenSize.height-472)/2, 632, 472);
    }// </editor-fold>//GEN-END:initComponents

    private void newBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newBtnActionPerformed
        new EditTemplateScrean(generaionService, templateRepository, this)
                .setVisible(true);
        refreshBtnActionPerformed(evt);
    }//GEN-LAST:event_newBtnActionPerformed

    private void refreshBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshBtnActionPerformed
        listModel.clear();
        for(TemplateBean b : templateRepository.getList()) {
            listModel.addElement(b);
        }
    }//GEN-LAST:event_refreshBtnActionPerformed

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
        System.exit(0);
    }//GEN-LAST:event_exitMenuItemActionPerformed

    private void refreshMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshMenuItemActionPerformed
        refreshBtnActionPerformed(evt);
    }//GEN-LAST:event_refreshMenuItemActionPerformed

    private void newTemplateMenyItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTemplateMenyItemActionPerformed
        newBtnActionPerformed(evt);
    }//GEN-LAST:event_newTemplateMenyItemActionPerformed

    private void deleteBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteBtnActionPerformed
        TemplateBean selectedTemplate = (TemplateBean) mainList.getSelectedValue();
        if (selectedTemplate != null) {
            try {
                templateRepository.remove(selectedTemplate);
            } catch (Exception ex) {
                UIUtil.niceEx(ex, getTitle(), "");
            }
        }
        refreshBtnActionPerformed(evt);
    }//GEN-LAST:event_deleteBtnActionPerformed

    private void editBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editBtnActionPerformed
        final TemplateBean selectedTemplate = (TemplateBean) mainList.getSelectedValue();
        if (selectedTemplate != null) {
            final String name = selectedTemplate.getName();
            final ProgressDialog progressDialog = new UIUtil.ProgressDialog(
                    this, getTitle(), "Open template " + name, true);
            //TODO: VERY weak plase!
            new Thread(new Runnable() {
                public void run() {
                    try {
                        EditTemplateScrean screan = new EditTemplateScrean(generaionService,
                                templateRepository, MainFrame.this);
                        screan.setEditingTemplate(templateRepository.get(
                                selectedTemplate.getId()), name);
                        progressDialog.setVisible(false);
                        screan.setVisible(true);
                    } catch (Exception ex) {
                        progressDialog.setVisible(false);
                        ex.printStackTrace(System.out);
                        UIUtil.niceEx(ex, getTitle(), "");
                    }
                }
            }).start();
            progressDialog.setVisible(true);
        }
    }//GEN-LAST:event_editBtnActionPerformed

    private void getBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_getBtnActionPerformed
        TemplateBean selectedTemplate = (TemplateBean) mainList.getSelectedValue();
        if (selectedTemplate != null) {
            JFileChooser fch = new JFileChooser();
            fch.setDialogType(JFileChooser.SAVE_DIALOG);
            fch.setFileSelectionMode(JFileChooser.FILES_ONLY);
            int returnVal = fch.showOpenDialog(this);

            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fch.getSelectedFile();
                try {
                    Template get = templateRepository.get(selectedTemplate.getId());
                    byte[] templateBinaryData = get.getTemplateBinaryData();
                    FileUtils.writeByteArrayToFile(file, templateBinaryData);
                    UIUtil.openInFileBrowser(file, getTitle());
                } catch (Exception ex) {
                    UIUtil.niceEx(ex, getTitle(), "");
                }
            }
        }
    }//GEN-LAST:event_getBtnActionPerformed

    private void deleteTemplateMenyItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTemplateMenyItemActionPerformed
        deleteBtnActionPerformed(evt);
    }//GEN-LAST:event_deleteTemplateMenyItemActionPerformed

    private void editTemplateMenyItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editTemplateMenyItemActionPerformed
        editBtnActionPerformed(evt);
    }//GEN-LAST:event_editTemplateMenyItemActionPerformed

    private void getTemplateMenyItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_getTemplateMenyItemActionPerformed
        getBtnActionPerformed(evt);
    }//GEN-LAST:event_getTemplateMenyItemActionPerformed

    private void settingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_settingsMenuItemActionPerformed
        try {
            SettingsScrean ss = new SettingsScrean(null, true,
                    templateRepository.getRepositoryFolder(),
                    connectionHolder.getDefaultDatabaseSettings());
            ss.setVisible(true);
            if (ss.getReturnStatus() == SettingsScrean.RET_OK) {
                DatabaseSettings dbSettings = ss.getDatabaseSettings();
                if (dbSettings.isEmpty()) {
                    connectionHolder.setDefaultDatabaseSettings(null);
                    defaultDatabaseSettingsFileName.delete();
                } else {
                    connectionHolder.setDefaultDatabaseSettings(dbSettings);
                    FileOutputStream fout = new FileOutputStream(
                            defaultDatabaseSettingsFileName);
                    XmlSerializator.write(dbSettings, fout);
                    fout.close();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
            UIUtil.niceEx(ex, getTitle(), "");
        }
    }//GEN-LAST:event_settingsMenuItemActionPerformed

    private void generateDocumentMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateDocumentMenuItemActionPerformed
        TemplateBean selectedTemplate = (TemplateBean) mainList.getSelectedValue();
        if (selectedTemplate != null) {
            try {
                Template get = templateRepository.get(selectedTemplate.getId());
                new DocGenerationPanel(this, true, generaionService, get).setVisible(true);
            } catch (Exception ex) {
                ex.printStackTrace(System.out);
                UIUtil.niceEx(ex, getTitle(), "");
            }
        }
    }//GEN-LAST:event_generateDocumentMenuItemActionPerformed

    private void generateDocumentFromXmlMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateDocumentFromXmlMenuItemActionPerformed
        File sf = UIUtil.openFileChooser(JFileChooser.OPEN_DIALOG, 
                bundle.getString("selectInputXml"));
        if (sf == null) {
            return;
        }

        InputStream fin = null;
        OutputStream fout = null;
        try {
            fin = new FileInputStream(sf);
            GenerationSettings gs = XmlSerializator.read(GenerationSettings.class,
                    IOUtils.toByteArray(fin));
            
            sf = UIUtil.openFileChooser(JFileChooser.SAVE_DIALOG, 
                    bundle.getString("selectOutputFile"));

            if (sf != null) {
                generaionService.generateDocument(gs, fout = FileUtils.openOutputStream(sf));

                UIUtil.openInFileBrowser(sf, getTitle());
            }
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
            UIUtil.niceEx(ex, getTitle(), "");
        } finally {
            IOUtils.closeQuietly(fout);
            IOUtils.closeQuietly(fin);
        }
    }//GEN-LAST:event_generateDocumentFromXmlMenuItemActionPerformed

    private void copyWithAnotherDataMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyWithAnotherDataMenuItemActionPerformed
        TemplateBean selectedTemplate = (TemplateBean) mainList.getSelectedValue();
        if (selectedTemplate != null) {
            try {
                new CopyTemplateScrean(this, true, templateRepository,
                        generaionService,
                        templateRepository.get(selectedTemplate.getId()),
                        "Copy of " + selectedTemplate.getName()).setVisible(true);
            } catch (Exception ex) {
                ex.printStackTrace(System.out);
                UIUtil.niceEx(ex, getTitle(), "");
            }
            refreshBtnActionPerformed(evt);
        }
    }//GEN-LAST:event_copyWithAnotherDataMenuItemActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JMenuItem copyWithAnotherDataMenuItem;
    private javax.swing.JButton deleteBtn;
    private javax.swing.JMenuItem deleteTemplateMenyItem;
    private javax.swing.JButton editBtn;
    private javax.swing.JMenuItem editTemplateMenyItem;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JMenuItem generateDocumentFromXmlMenuItem;
    private javax.swing.JMenuItem generateDocumentMenuItem;
    private javax.swing.JButton getBtn;
    private javax.swing.JMenuItem getTemplateMenyItem;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JMenuItem helpMenuItem;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JPopupMenu.Separator jSeparator3;
    private javax.swing.JList mainList;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JScrollPane mainScroll;
    private javax.swing.JMenu managementMenu;
    private javax.swing.JButton newBtn;
    private javax.swing.JMenuItem newTemplateMenyItem;
    private javax.swing.JButton refreshBtn;
    private javax.swing.JMenuItem refreshMenuItem;
    private javax.swing.JMenuItem settingsMenuItem;
    private javax.swing.JMenu templateMenu;
    private javax.swing.JPanel toolbarPanel;
    // End of variables declaration//GEN-END:variables

}
